import sys
import blue
import uthread
import uix
import uiutil
import mathUtil
import xtriui
import form
import trinity
import util
import base
import math
import log
import lg
import destiny
import uicls
import uiconst
ICONSIZE = 32
groups = ('hardpoints',
 'systems',
 'structure')

class ShipUI(uicls.LayerCore):
    __guid__ = 'form.ShipUI'
    __notifyevents__ = ['OnShipScanCompleted',
     'OnJamStart',
     'OnJamEnd',
     'OnCargoScanComplete',
     'ProcessShipEffect',
     'DoBallRemove',
     'DoBallClear',
     'OnAutoPilotOn',
     'OnAutoPilotOff',
     'OnAttributes',
     'ProcessRookieStateChange',
     'OnSetDevice',
     'OnMapShortcut',
     'OnRestoreDefaultShortcuts',
     'OnTacticalOverlayChange',
     'OnAssumeStructureControl',
     'OnRelinquishStructureControl',
     'OnWeaponGroupsChanged',
     'OnRefreshModuleBanks']

    def OnSetDevice(self):
        self.UpdatePosition()



    def ResetSelf(self):
        self.sr.wnd = None
        self.sr.speedtimer = None
        self.sr.capacitortimer = None
        self.sr.cargotimer = None
        self.sr.modeTimer = None
        self.sr.gaugetimer = None
        self.sr.gaugeReadout = None
        self.sr.selectedcateg = 0
        self.sr.pendingreloads = []
        self.sr.reloadsByID = {}
        self.sr.rampTimers = {}
        self.sr.main = None
        self.sr.powercore = None
        self.sr.powercolumn = None
        self.sr.speedNeedle = None
        self.sr.speedReadout = None
        self.sr.autopilotBtn = None
        self.sr.tacticalBtn = None
        self.sr.powerblink = None
        self.sr.speed_ro = None
        self.sr.shield_ro = None
        self.sr.armor_ro = None
        self.sr.powercore_ro = None
        self.sr.structure_ro = None
        self.sr.module_ro = None
        self.sr.currentModeHeader = None
        self.sr.hudButtons = None
        self.myHarpointFlags = []
        self.capacity = None
        self.shieldcapacity = None
        self.lastsetcapacitor = None
        self.lastsetshield = None
        self.lastsetarmor = None
        self.wantedspeed = None
        self.capacitorDone = 0
        self.sr.modules = {}
        self.ball = None
        self.initing = None
        self.initedshipid = None
        self.speedInited = 0
        self.updatingcargo = 0
        self.updatingspeed = 0
        self.slotsInited = 0
        self.jammers = {}
        self.speedupdatetimer = None
        self.genericupdatetimer = None
        self.assumingcontrol = False
        self.assumingdelay = None
        self.checkingoverloadrackstate = 0
        self.totalSlaves = 0
        self.timerNames = {'propulsion': mls.UI_INFLIGHT_SCRAMBLING,
         'electronic': mls.UI_INFLIGHT_JAMMING,
         'unknown': mls.UI_INFLIGHT_MISCELLANEOUS}



    def CheckPendingReloads(self):
        if self.sr.pendingreloads:
            rl = self.sr.pendingreloads[0]
            while (rl in self.sr.pendingreloads):
                self.sr.pendingreloads.remove(rl)

            module = self.GetModule(rl)
            if module:
                module.AutoReload()



    def CheckSession(self, change):
        if sm.GetService('autoPilot').GetState():
            self.OnAutoPilotOn()
        else:
            self.OnAutoPilotOff()



    def UpdatePosition(self):
        self.sr.wnd.height = 195
        self.sr.wnd.width = eve.triapp.uilib.desktop.width
        wndLeft = settings.user.windows.Get('shipuialignleft', 0)
        (maxRight, minLeft,) = self.GetShipuiOffsetMinMax()
        if ((wndLeft > maxRight) or (wndLeft < minLeft)):
            settings.user.windows.Set('shipuialignleft', 0)
            wndLeft = 0
        self.sr.wnd.left = wndLeft
        self.sr.wnd.align = uix.UI_ALABSOLUTE
        if not settings.user.ui.Get('shipuialigntop', 0):
            self.sr.wnd.top = (eve.triapp.uilib.desktop.height - self.sr.wnd.height)
        else:
            self.sr.wnd.top = 0
        if self.sr.gaugeReadout:
            self.sr.gaugeReadout.top = self.GetGaugeTop()
        if settings.user.ui.Get('shipuialigntop', 0):
            self.sr.indicationContainer.top = 200
        else:
            self.sr.indicationContainer.top = -50
        self.sr.timers.top = ((eve.triapp.uilib.desktop.height - self.sr.timers.height) - 205)
        self.sr.timers.left = ((eve.triapp.uilib.desktop.width - self.sr.timers.width) / 2)



    def GetGaugeTop(self, *args):
        if settings.user.ui.Get('shipuialigntop', 0):
            return 20
        else:
            return 200



    def GetShipLayerAbsolutes(self):
        d = eve.triapp.uilib.desktop
        wnd = uicore.layer.shipui
        if (wnd and (not (wnd.state == uix.UI_HIDDEN))):
            (pl, pt, pw, ph,) = wnd.GetAbsolute()
        else:
            (pl, pt, pw, ph,) = d.GetAbsolute()
        return (wnd,
         pl,
         pt,
         pw,
         ph)



    def GetShipUI(self, obj):
        return self.sr.wnd



    def OnShipMouseDown(self, wnd, btn, *args):
        if (btn != 0):
            return 
        self.dragging = True
        wnd = self.GetShipUI(wnd)
        if not wnd:
            return 
        (l, t, w, h,) = wnd.GetAbsolute()
        self.grab = [(eve.triapp.uilib.x - l), (eve.triapp.uilib.y - t)]
        uthread.new(self.BeginDrag, wnd)



    def GetShipuiOffsetMinMax(self, *args):
        maxRight = ((eve.triapp.uilib.desktop.width / 2) - (self.sr.slotsContainer.width / 2))
        minLeft = -((eve.triapp.uilib.desktop.width / 2) - 180)
        return (maxRight, minLeft)



    def OnShipMouseUp(self, wnd, btn, *args):
        if (btn != 0):
            return 
        wnd = self.GetShipUI(wnd)
        if wnd:
            wndLeft = settings.user.windows.Set('shipuialignleft', wnd.left)
        sm.StartService('ui').ForceCursorUpdate()
        self.dragging = False



    def BeginDrag(self, wnd):
        wnd = self.GetShipUI(wnd)
        while ((not wnd.destroyed) and getattr(self, 'dragging', 0)):
            eve.triapp.uilib.SetCursor(8)
            (maxRight, minLeft,) = self.GetShipuiOffsetMinMax()
            grabLocation = (eve.triapp.uilib.x - self.grab[0])
            wnd.left = max(minLeft, min(maxRight, grabLocation))
            blue.pyos.synchro.Sleep(1)




    def OnOpenView(self):
        bp = sm.GetService('michelle').GetBallpark()
        if ((bp is None) or (eve.session.shipid is None)):
            return 
        ball = bp.GetBall(eve.session.shipid)
        self.ResetSelf()
        self.state = uix.UI_HIDDEN
        self.sr.wnd = blue.os.LoadObject('res:/UI/Component/shipui.blue')
        uthread.pool('ShipUI-->TryLoadUIColors', sm.GetService('window').TryLoadUIColors)
        timers = uicls.Container(name='timers', parent=self, width=120, height=450, align=uiconst.ABSOLUTE)
        self.sr.timers = timers
        self.sr.mainContainer = uiutil.GetChild(self.sr.wnd, 'mainContainer')
        self.sr.subContainer = uiutil.GetChild(self.sr.wnd, 'subContainer')
        self.sr.slotsContainer = uiutil.GetChild(self.sr.wnd, 'slotsContainer')
        if settings.user.ui.Get('shipuialigntop', 0):
            top = 200
        else:
            top = -50
        self.sr.indicationContainer = uicls.Container(parent=self.sr.wnd, align=uiconst.CENTERTOP, pos=(0,
         top,
         400,
         50))
        showReadout = settings.user.ui.Get('showReadout', 0)
        if showReadout:
            self.InitGaugeReadout()
        self.children.insert(0, self.sr.wnd)
        self.sr.powercore = uicls.Container(uiutil.GetChild(self.sr.wnd, 'powercore'))
        self.sr.powercore.OnMouseDown = self.OnShipMouseDown
        self.sr.powercore.OnMouseUp = self.OnShipMouseUp
        self.sr.powercore.GetMenu = self.GetMenu
        self.sr.powercolumn = uiutil.GetChild(self.sr.wnd, 'powerColumn')
        mExpanded = settings.user.ui.Get('modulesExpanded', 1)
        self.sr.expandbtnleft = uicls.Sprite(uiutil.GetChild(self.sr.wnd, 'expandBtnLeft'))
        self.sr.expandbtnleft.OnClick = self.ClickExpand
        self.sr.expandbtnleft.OnMouseDown = self.OnExpandDown
        self.sr.expandbtnleft.OnMouseUp = self.OnExpandUp
        self.sr.expandbtnleft.side = -1
        self.sr.expandbtnleft.hint = [mls.UI_INFLIGHT_SHOWBUTTONS, mls.UI_INFLIGHT_HIDEBUTTONS][mExpanded]
        self.sr.expandbtnright = uicls.Sprite(uiutil.GetChild(self.sr.wnd, 'expandBtnRight'))
        self.sr.expandbtnright.OnClick = self.ClickExpand
        self.sr.expandbtnright.side = 1
        self.sr.expandbtnright.OnMouseDown = self.OnExpandDown
        self.sr.expandbtnright.OnMouseUp = self.OnExpandUp
        self.sr.expandbtnright.hint = [mls.UI_INFLIGHT_SHOWMODULES, mls.UI_INFLIGHT_HIDEMODULES][mExpanded]
        options = uicls.Icon(uiutil.GetChild(self.sr.wnd, 'optionsBtn'))
        options.ChangeIcon(icon='ui_77_32_49', size=24, ignoreSize=True)
        options.SetAlpha(0.8)
        options.width = 24
        options.height = 24
        options.OnMouseEnter = self.OptionsBtnMouseEnter
        options.OnMouseExit = self.OptionsBtnMouseExit
        options.GetMenu = self.GetOptionMenu
        options.expandOnLeft = 1
        options.sr.hint = mls.UI_GENERIC_OPTIONS
        self.options = options
        self.sr.structureGauge = xtriui.SlimDeco(uiutil.GetChild(self.sr.wnd, 'structureGauge'))
        self.sr.armorGauge = xtriui.SlimDeco(uiutil.GetChild(self.sr.wnd, 'armorGauge'))
        self.sr.shieldGauge = xtriui.SlimDeco(uiutil.GetChild(self.sr.wnd, 'shieldGauge'))
        omg = uiutil.GetChild(self.sr.wnd, 'orgMiniGauge')
        for (typeName, deg,) in [('low', -22.5),
         ('med', -90.0),
         ('hi', -157.5)]:
            gauge = omg.CopyTo()
            omg.parent.children.insert(0, gauge)
            gauge.transform.RotationZ(mathUtil.DegToRad(deg))
            self.sr.Set(('%sHeatGauge' % typeName), gauge)
            underlay = uiutil.FindChild(self.sr.wnd, ('heat%sUnderlay' % typeName.capitalize()))
            if underlay:
                self.sr.Set(('heat%sUnderlay' % typeName.capitalize()), underlay)

        omg.Close()
        self.sr.heatPick = xtriui.SlimDeco(uiutil.GetChild(self.sr.wnd, 'heatPick'))
        for each in (self.sr.shieldGauge,
         self.sr.armorGauge,
         self.sr.structureGauge,
         self.sr.heatPick):
            each.LoadEvents(['Close',
             'MouseMove',
             'MouseEnter',
             'MouseExit'])

        self.sr.wnd.state = uix.UI_PICKCHILDREN
        self.cookie = sm.GetService('inv').Register(self)
        sm.RegisterNotify(self)
        if (ball is not None):
            self.Init(ball)
        self.DoInit()
        self.UpdatePosition()



    def OptionsBtnMouseEnter(self, *args):
        self.options.SetAlpha(1.0)



    def OptionsBtnMouseExit(self, *args):
        self.options.SetAlpha(0.8)



    def DoInit(self):
        self.InitButtons()
        self.SetButtonState()
        self.CheckExpandBtns()
        self.CheckControl()



    def CheckControl(self):
        control = sm.GetService('pwn').GetCurrentControl()
        if control:
            self.OnAssumeStructureControl()



    def SetButtonState(self):
        self.sr.slotsContainer.state = [uix.UI_HIDDEN, uix.UI_PICKCHILDREN][settings.user.ui.Get('modulesExpanded', 1)]
        self.sr.hudButtons.state = [uix.UI_HIDDEN, uix.UI_PICKCHILDREN][settings.user.ui.Get('hudButtonsExpanded', 1)]



    def InitGaugeReadout(self):
        self.sr.gaugeReadout = uicls.Container(name='gaugeReadout', parent=self.sr.mainContainer, left=((self.sr.mainContainer.width / 2) + 54), top=self.GetGaugeTop(), align=uiconst.TOPLEFT)
        self.sr.gaugeReadout.anchors = uix.UI_ANCHBOTTOM
        for (left, group,) in [(20, ('shield', 'armor', 'structure'))]:
            top = 0
            for refName in group:
                t = uicls.Label(text='Xg', parent=self.sr.gaugeReadout, left=left, top=top, state=uiconst.UI_DISABLED, fontsize=9, linespace=9, letterspace=1, uppercase=1)
                self.sr.gaugeReadout.sr.Set(refName, t)
                left -= 10
                top += t.textheight
                t.text = ''


        self.sr.gaugeReadout.height = top



    def OnMapShortcut(self, *blah):
        self.RefreshShortcuts()



    def OnRestoreDefaultShortcuts(self):
        self.RefreshShortcuts()



    def OnAssumeStructureControl(self, *args):
        now = blue.os.GetTime()
        self.assumingdelay = now
        uthread.new(self.DelayedOnAssumeStructureControl, now)



    def DelayedOnAssumeStructureControl(self, issueTime):
        blue.pyos.synchro.Sleep(250)
        if (self.assumingdelay is None):
            return 
        issuedAt = self.assumingdelay
        if (issuedAt != issueTime):
            return 
        self.assumingdelay = None
        self.ShowStructureControl()



    def ShowStructureControl(self, *args):
        control = sm.GetService('pwn').GetCurrentControl()
        if control:
            for each in uicore.layer.shipui.children[0].children:
                if (each.name in ('hudbuttons', 'slotsContainer')):
                    continue
                each.state = uix.UI_HIDDEN

            self.assumingcontrol = True
            self.initing = 1
            self.InitSlots()
            settings.user.ui.Set('modulesExpanded', 1)
            settings.user.ui.Set('hudButtonsExpanded', 1)
            self.InitButtons()
            self.initing = 0
            uicore.effect.MorphUI(self.sr.slotsContainer, 'left', -80, 500.0)
            uicore.effect.MorphUI(self.sr.hudButtons, 'left', 80, 500.0)



    def OnRelinquishStructureControl(self, *args):
        control = sm.GetService('pwn').GetCurrentControl()
        if not control:
            for each in uicore.layer.shipui.children[0].children:
                each.state = uix.UI_PICKCHILDREN

            self.assumingcontrol = False
            uicore.effect.MorphUI(self.sr.slotsContainer, 'left', 0, 500.0)
            uicore.effect.MorphUI(self.sr.hudButtons, 'left', 0, 500.0)
        self.initing = 1
        self.InitSlots()
        self.DoInit()
        self.initing = 0



    def OnWeaponGroupsChanged(self):
        if ((not self) or self.destroyed):
            return 
        uthread.new(self.InitSlots)



    def OnRefreshModuleBanks(self):
        if ((not self) or self.destroyed):
            return 
        uthread.new(self.InitSlots)



    def RefreshShortcuts(self):
        for ((r, i,), slot,) in self.sr.slotsByOrder.iteritems():
            hiMedLo = ('High', 'Medium', 'Low')[r]
            slotno = (i + 1)
            txt = uicore.cmd.GetShortcutStringByFuncName(('CmdActivate%sPowerSlot%i' % (hiMedLo, slotno)))
            if not txt:
                txt = '_'
            slot.sr.shortcutHint.text = ('<center>' + txt)




    def BlinkButton(self, key):
        btn = (self.sr.Get(key.lower(), None) or self.sr.Get(('%sBtn' % key.lower()), None))
        if not btn:
            for each in self.sr.modules:
                if (getattr(each, 'locationFlag', None) == util.LookupConstValue(('flag%s' % key), 'no')):
                    btn = each
                    break

        if not btn:
            return 
        if hasattr(btn.sr, 'icon'):
            sm.GetService('ui').BlinkSpriteA(btn.sr.icon, 1.0, 1000, None, passColor=0)
        else:
            sm.GetService('ui').BlinkSpriteA(btn, 1.0, 1000, None, passColor=0)



    def GetOptionMenu(self):
        m = []
        if not eve.rookieState:
            showPassive = settings.user.ui.Get('showPassiveModules', 1)
            m += [([mls.UI_INFLIGHT_SHOWPASSIVEMODULES, mls.UI_INFLIGHT_HIDEPASSIVEMODULES][showPassive], self.ToggleShowPassive)]
            showEmpty = settings.user.ui.Get('showEmptySlots', 0)
            m += [([mls.UI_INFLIGHT_SHOWEMPTYSLOTS, mls.UI_INFLIGHT_HIDEEMPTYSLOTS][showEmpty], self.ToggleShowEmpty)]
            lockModules = settings.user.ui.Get('lockModules', 0)
            m += [([mls.UI_INFLIGHT_LOCKMODULES, mls.UI_INFLIGHT_UNLOCKMODULES][lockModules], self.ToggleLockModules)]
            lockOverload = settings.user.ui.Get('lockOverload', 0)
            m += [([mls.UI_CMD_LOCKOVERLOADSTATE, mls.UI_CMD_UNLOCKOVERLOADSTATUS][lockOverload], self.ToggleOverloadLock)]
        showReadout = settings.user.ui.Get('showReadout', 0)
        readoutType = settings.user.ui.Get('readoutType', 1)
        m += [([mls.UI_INFLIGHT_SHOWREADOUT, mls.UI_INFLIGHT_HIDEREADOUT][showReadout], self.ToggleReadout)]
        m += [([mls.UI_INFLIGHT_PERCENTAGEREADOUT, mls.UI_INFLIGHT_ABSOLUTEREADOUT][readoutType], self.ToggleReadoutType)]
        showZoomBtns = settings.user.ui.Get('showZoomBtns', 0)
        m += [([mls.UI_INFLIGHT_SHOWZOOMBTNS, mls.UI_INFLIGHT_HIDEZOOMBTNS][showZoomBtns], self.ToggleShowZoomBtns)]
        showCycleTimer = settings.user.ui.Get('showCycleTimer', 1)
        if showCycleTimer:
            cycleText = mls.UI_SHARED_ACTIVATIONTIMEROFF
        else:
            cycleText = mls.UI_SHARED_ACTIVATIONTIMERON
        m += [(cycleText, self.ToggleCycleTimer)]
        m += [None]
        m += [(mls.UI_GENERIC_NOTIFYSETTINGS, self.ShowNotifySettingsWindow)]
        m += [None]
        alignTop = settings.user.ui.Get('shipuialigntop', 0)
        m += [([mls.UI_CMD_ALIGNTOP, mls.UI_CMD_ALIGNBOTTOM][alignTop], self.ToggleAlign)]
        return m



    def ShowNotifySettingsWindow(self):
        window = sm.GetService('window').GetWindow('NotifySettingsWindow', create=1)
        window.Maximize()



    def ToggleAlign(self):
        settings.user.ui.Set('shipuialigntop', (not settings.user.ui.Get('shipuialigntop', 0)))
        self.UpdatePosition()



    def ToggleReadout(self):
        current = (not settings.user.ui.Get('showReadout', 0))
        settings.user.ui.Set('showReadout', current)
        if (self.sr.gaugeReadout is None):
            self.InitGaugeReadout()
        self.sr.gaugeReadout.state = [uix.UI_HIDDEN, uix.UI_PICKCHILDREN][current]



    def ToggleReadoutType(self):
        current = settings.user.ui.Get('readoutType', 1)
        settings.user.ui.Set('readoutType', (not current))



    def ToggleCycleTimer(self):
        current = settings.user.ui.Get('showCycleTimer', 1)
        settings.user.ui.Set('showCycleTimer', (not current))
        self.InitSlots()



    def ToggleShowPassive(self):
        settings.user.ui.Set('showPassiveModules', (not settings.user.ui.Get('showPassiveModules', 1)))
        self.InitSlots()



    def ToggleShowZoomBtns(self):
        settings.user.ui.Set('showZoomBtns', (not settings.user.ui.Get('showZoomBtns', 0)))
        self.InitButtons()



    def ToggleShowEmpty(self):
        settings.user.ui.Set('showEmptySlots', (not settings.user.ui.Get('showEmptySlots', 0)))
        self.InitSlots()



    def ToggleLockModules(self):
        settings.user.ui.Set('lockModules', (not settings.user.ui.Get('lockModules', 0)))
        self.CheckGroupAllButton()



    def ToggleOverloadLock(self):
        settings.user.ui.Set('lockOverload', (not settings.user.ui.Get('lockOverload', 0)))



    def ShowTimer(self, timerID, startTime, duration, label):
        check = self.GetTimer(timerID)
        if check:
            if (check.endTime <= (startTime + duration)):
                check.Close()
            else:
                return 
        timer = uicls.Container(name=('%s' % timerID), parent=self.sr.timers, height=17, align=uiconst.TOBOTTOM, top=30)
        timer.endTime = (startTime + duration)
        uicls.Label(text=label, parent=timer, left=124, top=-1, fontsize=9, letterspace=2, linespace=8, color=(1.0, 1.0, 1.0, 0.5), uppercase=1, state=uiconst.UI_NORMAL)
        fpar = uicls.Container(parent=timer, align=uiconst.TOTOP, height=13)
        uicls.Frame(parent=fpar, color=(1.0, 1.0, 1.0, 0.5))
        t = uicls.Label(text='', parent=fpar, left=5, top=1, fontsize=9, letterspace=1, uppercase=1, state=uiconst.UI_NORMAL)
        p = uicls.Fill(parent=fpar, align=uiconst.TOPLEFT, width=118, height=11, left=1, top=1, color=(1.0, 1.0, 1.0, 0.25))
        duration = float(duration)
        totalTime = (float(((startTime + (duration * 10000)) - blue.os.GetTime())) / SEC)
        while (1 and (not timer.destroyed)):
            now = blue.os.GetTime()
            dt = blue.os.TimeDiffInMs(startTime, now)
            timeLeft = ((duration - dt) / 1000.0)
            timer.timeLeft = timeLeft
            if (timer.destroyed or (dt > duration)):
                t.text = mls.UI_GENERIC_DONE
                p.width = 0
                break
            t.text = ('%.3f %s' % (timeLeft, uix.Plural(timeLeft, 'UI_GENERIC_SECONDSHORT')))
            p.width = max(0, min(118, int((118 * (timeLeft / totalTime)))))
            blue.pyos.synchro.Yield()

        if not timer.destroyed:
            blue.pyos.synchro.Sleep(250)
            if not t.destroyed:
                t.text = ''
            blue.pyos.synchro.Sleep(250)
            if not t.destroyed:
                t.text = mls.UI_GENERIC_DONE
            blue.pyos.synchro.Sleep(250)
            if not t.destroyed:
                t.text = ''
            blue.pyos.synchro.Sleep(250)
            if not t.destroyed:
                t.text = mls.UI_GENERIC_DONE
            blue.pyos.synchro.Sleep(250)
            if not t.destroyed:
                t.text = ''
            if not timer.destroyed:
                timer.Close()



    def KillTimer(self, timerID):
        timer = self.GetTimer(timerID)
        if timer:
            timer.Close()



    def GetTimer(self, timerID):
        for each in self.sr.timers.children:
            if (each.name == ('%s' % timerID)):
                return each




    def OnExpandDown(self, btn, *args):
        return 



    def OnExpandUp(self, btn, *args):
        return 



    def ClickExpand(self, btn, *args):
        if (btn.side == -1):
            if self.sr.hudButtons:
                self.sr.hudButtons.state = [uix.UI_PICKCHILDREN, uix.UI_HIDDEN][(self.sr.hudButtons.state == uix.UI_PICKCHILDREN)]
            settings.user.ui.Set('hudButtonsExpanded', (self.sr.hudButtons.state == uix.UI_PICKCHILDREN))
        elif self.sr.slotsContainer:
            self.sr.slotsContainer.state = [uix.UI_PICKCHILDREN, uix.UI_HIDDEN][(self.sr.slotsContainer.state == uix.UI_PICKCHILDREN)]
        settings.user.ui.Set('modulesExpanded', (self.sr.slotsContainer.state == uix.UI_PICKCHILDREN))
        sm.GetService('ui').StopBlink(btn)
        self.CheckExpandBtns()



    def CheckExpandBtns(self):
        if (self.sr.Get('expandbtnright', None) and (not self.sr.expandbtnright.destroyed)):
            on = settings.user.ui.Get('modulesExpanded', 1)
            self.sr.expandbtnright.rectLeft = [0, 28][on]
            self.sr.expandbtnright.hint = [mls.UI_INFLIGHT_SHOWMODULES, mls.UI_INFLIGHT_HIDEMODULES][on]
        else:
            return 
        if self.sr.Get('expandbtnleft', None):
            on = settings.user.ui.Get('hudButtonsExpanded', 1)
            self.sr.expandbtnleft.rectLeft = [28, 0][on]
            self.sr.expandbtnleft.hint = [mls.UI_INFLIGHT_SHOWBUTTONS, mls.UI_INFLIGHT_HIDEBUTTONS][on]



    def InitButtons(self):
        par = uiutil.FindChild(self.sr.wnd, 'hudbuttons')
        if not par:
            par = uicls.Container(name='hudbuttons', parent=self.sr.slotsContainer.parent, align=uiconst.CENTER, pos=(0, 0, 512, 256))
        uix.Flush(par)
        grid = [[-1.0, -1.0],
         [-1.5, 0.0],
         [-1.0, 1.0]]
        btn = blue.os.LoadObject('res:/UI/Component/shipui_shortcut.blue')
        w = par.width
        h = par.height
        centerX = ((w - btn.width) / 2)
        centerY = ((h - btn.height) / 2)
        ystep = int((ICONSIZE * 1.06))
        xstep = int((ICONSIZE * 1.3))
        step = 20
        buttons = [(mls.UI_GENERIC_CARGO,
          'inFlightCargoBtn',
          'Cargo',
          '44_10',
          100,
          -1.0,
          'OpenCargoHoldOfActiveShip'),
         (mls.UI_CMD_RESETCAMERA,
          'inFlightResetCameaBtn',
          'ResetCamera',
          '44_46',
          128,
          0.5,
          ''),
         (mls.UI_GENERIC_SCANNER,
          'inFlightScannerBtn',
          'Scanner',
          '44_41',
          100,
          0.0,
          'OpenScanner'),
         (mls.UI_GENERIC_TACTICAL,
          'inFlightTacticalBtn',
          'Tactical',
          '44_42',
          128,
          -0.5,
          'CmdToggleTacticalOverlay'),
         (mls.UI_GENERIC_AUTOPILOT,
          'inFlightAutopilotBtn',
          'Autopilot',
          '44_12',
          100,
          1.0,
          'CmdToggleAutopilot')]
        showZoomBtns = settings.user.ui.Get('showZoomBtns', 0)
        if showZoomBtns:
            buttons += [(mls.UI_CMD_ZOOMIN,
              'inFlightZoomInBtn',
              'ZoomIn',
              '44_43',
              128,
              1.5,
              'CmdZoomIn'), (mls.UI_CMD_ZOOMOUT,
              'inFlightZoomOutBtn',
              'ZoomOut',
              '44_44',
              100,
              2.0,
              'CmdZoomOut')]
        for (btnName, guiID, func, iconNum, rad, y, cmdName,) in buttons:
            if (eve.rookieState and (eve.rookieState < sm.GetService('tutorial').GetShipuiRookieFilter(btnName))):
                continue
            slot = uicls.Container(btn.CopyTo())
            slot.left = int((centerX - rad))
            slot.top = (int((centerY + (y * 31))) - (showZoomBtns * 16))
            slot.sr.hint = btnName
            slot.name = guiID
            slot.func = func
            self.sr.Set(btnName.replace(' ', '').lower(), slot)
            slot.OnClick = self.HudBtn_OnClick
            slot.OnMouseDown = self.HudBtn_OnMouseDown
            slot.OnMouseUp = self.HudBtn_OnMouseUp
            slot.OnMouseEnter = self.HudBtn_OnMouseEnter
            slot.OnMouseExit = self.HudBtn_OnMouseExit
            slot.sr.hilite = uiutil.GetChild(slot, 'hilite')
            slot.sr.icon = uiutil.GetChild(slot, 'icon')
            slot.cmdName = cmdName
            uix.MapSprite(iconNum, slot.sr.icon, scaling=0.125)
            par.children.append(slot)
            if (btnName == mls.UI_GENERIC_TACTICAL):
                self.sr.tacticalBtn = slot
                tActive = settings.user.overview.Get('viewTactical', 0)
                uiutil.GetChild(self.sr.tacticalBtn, 'busy').state = [uix.UI_HIDDEN, uix.UI_DISABLED][tActive]
                self.sr.tacticalBtn.sr.hint = [mls.UI_CMD_SHOWTACTICALOVERLEY, mls.UI_CMD_HIDETACTICALOVERLEY][tActive]
            elif (btnName == mls.UI_GENERIC_AUTOPILOT):
                self.sr.autopilotBtn = slot
                apActive = sm.GetService('autoPilot').GetState()
                uiutil.GetChild(self.sr.autopilotBtn, 'busy').state = [uix.UI_HIDDEN, uix.UI_DISABLED][apActive]
                self.sr.autopilotBtn.sr.hint = [mls.UI_CMD_ACTIVATEAUTOPILOT, mls.UI_CMD_DEACTIVATEAUTOPILOT][apActive]
            elif (btnName == mls.UI_GENERIC_CARGO):
                slot.OnDropData = self.DropInCargo
            slot.sr.hint += self._GetShortcutForCommand(cmdName)

        self.sr.hudButtons = par



    def _GetShortcutForCommand(self, cmdName):
        if cmdName:
            shortcut = uicore.cmd.GetShortcutStringByFuncName(cmdName)
            if shortcut:
                return (' [%s]' % shortcut)
            return ''



    def HudBtn_OnClick(self, btn, *args):
        funcName = btn.func
        if hasattr(self, funcName):
            getattr(self, funcName)()
        sm.GetService('ui').StopBlink(btn.sr.icon)



    def HudBtn_OnMouseDown(self, btn, *args):
        if (getattr(btn, 'orgTop', None) is None):
            btn.orgTop = btn.top
        btn.top = (btn.orgTop + 2)



    def HudBtn_OnMouseUp(self, btn, *args):
        if (getattr(btn, 'orgTop', None) is not None):
            btn.top = btn.orgTop



    def HudBtn_OnMouseEnter(self, btn, *args):
        btn.sr.hilite.state = uix.UI_DISABLED



    def HudBtn_OnMouseExit(self, btn, *args):
        btn.sr.hilite.state = uix.UI_HIDDEN
        if (getattr(btn, 'orgTop', None) is not None):
            btn.top = btn.orgTop



    def DropInCargo(self, dragObj, nodes):
        bms = []
        inv = []
        for node in nodes:
            if (node.Get('__guid__', None) == 'listentry.PlaceEntry'):
                bms.append(node)
            elif (node.rec and cfg.IsShipFittingFlag(node.rec.flagID)):
                if (node.rec.categoryID == const.categoryCharge):
                    sm.GetService('godma').GetStateManager().UnloadChargeToContainer(node.itemID, (session.shipid), const.flagCargo)
                else:
                    sm.GetService('godma').GetStateManager().UnloadModuleToContainer(node.itemID, (session.shipid))
            else:
                if (node.Get('__guid__', None) in ('xtriui.InvItem', 'listentry.InvItem')):
                    inv.append(node)

        if ((len(inv) > 0) and sm.GetService('consider').ConfirmTakeFromContainer(inv[0].rec.locationID)):
            if (len(inv) > 1):
                eve.GetInventoryFromId(eve.session.shipid).MultiAdd([ node.itemID for node in inv ], inv[0].rec.locationID, flag=const.flagCargo)
            else:
                eve.GetInventoryFromId(eve.session.shipid).Add(inv[0].itemID, inv[0].rec.locationID, flag=const.flagCargo)
        if (len(bms) > 0):
            uthread.new(self.AddBookmarks, [ node.bm.bookmarkID for node in bms ])



    def AddBookmarks(self, bookmarkIDs):
        isMove = (not eve.triapp.uilib.Key(uix.VK_SHIFT))
        eve.GetInventoryFromId(eve.session.shipid).AddBookmarks(bookmarkIDs, const.flagCargo, isMove)



    def Tactical(self, *args):
        sm.GetService('tactical').ToggleOnOff()
        tActive = settings.user.overview.Get('viewTactical', 0)
        uiutil.GetChild(self.sr.tacticalBtn, 'busy').state = [uix.UI_HIDDEN, uix.UI_DISABLED][tActive]
        self.sr.tacticalBtn.sr.hint = [mls.UI_CMD_SHOWTACTICALOVERLEY, mls.UI_CMD_HIDETACTICALOVERLEY][tActive]
        self.sr.tacticalBtn.sr.hint += self._GetShortcutForCommand(self.sr.tacticalBtn.cmdName)



    def Autopilot(self, *args):
        self.AutoPilotOnOff((not sm.GetService('autoPilot').GetState()))



    def ZoomIn(self, *args):
        uicore.cmd.CmdZoomIn()



    def ZoomOut(self, *args):
        uicore.cmd.CmdZoomOut()



    def ResetCamera(self, *args):
        sm.GetService('camera').ResetCamera()



    def Cargo(self, *args):
        self.ToggleCargo()



    def ToggleCargo(self):
        if eve.session.shipid:
            wnd = sm.GetService('window').GetWindow(('shipCargo_%s' % eve.session.shipid))
            if wnd:
                if wnd._minimized:
                    wnd.Maximize()
                elif wnd._collapsed:
                    wnd.Expand()
                else:
                    wnd.CloseX()
            else:
                shipName = cfg.evelocations.Get(eve.session.shipid).name
                sm.GetService('window').OpenCargo(eve.session.shipid, shipName, ('%s%s %s' % (shipName,
                 mls.AGT_AGENTMGR_FORMATMESSAGE_APPEND_APOSTROPHE_AND_S,
                 mls.UI_GENERIC_CARGO)))



    def Scanner(self, *args):
        self.ToggleScanner()



    def ToggleScanner(self):
        if eve.session.solarsystemid:
            wnd = sm.GetService('window').GetWindow('scanner', showIfInStack=False)
            if ((wnd is not None) and (not wnd.destroyed)):
                if wnd.IsMinimized():
                    wnd.Maximize()
                elif wnd.IsCollapsed():
                    wnd.Expand()
                else:
                    wnd.CloseX()
            else:
                sm.GetService('window').GetWindow('scanner', create=1, decoClass=form.Scanner)



    def InitStructureSlots(self):
        currentControl = sm.GetService('pwn').GetCurrentControl()
        btn = uicls.Container(name='defenceslot', parent=self.sr.slotsContainer, width=64, height=(128 + 60), align=uiconst.TOPLEFT, left=0, top=0)
        shipmodules = []
        charges = {}
        if currentControl:
            for (k, v,) in currentControl.iteritems():
                shipmodules.append(sm.services['godma'].GetItem(k))

        xstep = int((ICONSIZE * 2.0))
        ystep = int((ICONSIZE * 1.35))
        vgridrange = 1
        hgridrange = 5
        grid = [[1.0, 0.1]]
        myOrder = [0,
         1,
         2,
         3,
         4]
        for (i, moduleInfo,) in enumerate(shipmodules):
            if (moduleInfo is None):
                continue
            myOrder[i] = moduleInfo.itemID
            if currentControl.has_key(moduleInfo.itemID):
                item = sm.services['godma'].GetItem(moduleInfo.itemID)
                if ((item.groupID == const.groupMobileLaserSentry) and len(item.modules)):
                    charges[moduleInfo.itemID] = item.modules[0]
                else:
                    if len(item.sublocations):
                        charges[moduleInfo.itemID] = item.sublocations[0]

        self.InitDrawSlots(btn, xstep, ystep, vgridrange, hgridrange, grid, myOrder)
        for moduleInfo in shipmodules:
            if moduleInfo:
                self._FitStructureSlot(moduleInfo, charges)

        self.CheckButtonVisibility(3, ['hiSlots'], 5, myOrder)
        self.slotsInited = 1



    def InitDrawSlots(self, btn, xstep, ystep, vgridrange, hgridrange, grid, myOrder):
        w = self.sr.slotsContainer.width
        h = self.sr.slotsContainer.height
        centerX = ((w - btn.width) / 2)
        centerY = ((h - btn.height) / 2)
        for r in xrange(vgridrange):
            (x, y,) = grid[r]
            for i in xrange(hgridrange):
                slotFlag = myOrder[((r * hgridrange) + i)]
                slot = Slot(btn.CopyTo())
                slot.left = (int((centerX + ((x + i) * xstep))) + 50)
                slot.top = int((centerY + (ystep * y)))
                self.sr.slotsContainer.children.insert(0, slot)
                slot.sr.module = None
                slot.sr.slotFlag = slotFlag
                slot.sr.slotPos = (r, i)
                self.sr.slotsByFlag[slotFlag] = slot
                self.sr.slotsByOrder[(r, i)] = slot
                slot.state = uix.UI_HIDDEN
                slot.sr.shortcutHint = uicls.Label(text='<center>-', parent=slot, width=64, autowidth=False, color=(1.0, 1.0, 1.0, 0.25), shadow=[], state=uiconst.UI_DISABLED, fontsize=9, letterspace=1, linespace=8, idx=0)
                slot.sr.shortcutHint.top = 30
                if self.assumingcontrol:
                    slot.sr.shortcutHint.top -= 4


        self.RefreshShortcuts()



    def InitSlots(self):
        if ((not self) or ((not hasattr(self, 'sr')) or (not self.sr.Get('slotsContainer')))):
            return 
        uix.Flush(self.sr.slotsContainer)
        self.sr.modules = {}
        self.sr.slotsByFlag = {}
        self.sr.slotsByOrder = {}
        self.totalSlaves = 0
        control = sm.GetService('pwn').GetCurrentControl()
        if control:
            self.assumingcontrol = True
        else:
            self.assumingcontrol = False
        ship = sm.GetService('godma').GetItem(eve.session.shipid)
        if (ship is None):
            raise RuntimeError('ShipUI being inited with no ship state!')
        self.passiveFiltered = []
        if self.assumingcontrol:
            self.InitStructureSlots()
        else:
            btn = blue.os.LoadObject('res:/UI/Component/shipslot_32_n.blue')
            shipmodules = ship.modules
            charges = {}
            for sublocation in ship.sublocations:
                charges[sublocation.flagID] = sublocation
                if (sublocation.stacksize == 0):
                    sm.services['godma'].LogError('InitSlots.no quantity', sublocation, sublocation.flagID)

            for module in shipmodules:
                if (module.categoryID == const.categoryCharge):
                    charges[module.flagID] = module

            xstep = int((ICONSIZE * 1.6))
            ystep = int((ICONSIZE * 1.4))
            vgridrange = 3
            hgridrange = 8
            grid = [[1.0, -1.0],
             [1.5, 0.0],
             [1.0, 1.0]]
            myOrder = self.GetSlotOrder()
            self.InitDrawSlots(btn, xstep, ystep, vgridrange, hgridrange, grid, myOrder)
            self.InitOverloadBtns(grid, shipmodules)
            self.InitGroupAllButtons()
            godmaStateManager = sm.StartService('godma').GetStateManager()
            IsSlave = godmaStateManager.IsSlaveModule
            groupableModuleGroups = godmaStateManager.GetGroupableModuleGroups()
            for moduleInfo in shipmodules:
                if IsSlave(moduleInfo.itemID):
                    self.totalSlaves += 1
                    continue
                self._FitSlot(moduleInfo, charges)

            self.CheckButtonVisibility(0, ['hiSlots',
             'medSlots',
             'lowSlots'], None, myOrder)
            self.slotsInited = 1



    def InitGroupAllButtons(self):
        w = self.sr.slotsContainer.width
        h = self.sr.slotsContainer.height
        centerX = ((w - 20) / 2)
        centerY = ((h - 20) / 2)
        ic = uicls.Icon(parent=self.sr.slotsContainer, icon='ui_73_16_251', idx=0, name='groupAllIcon', pos=((centerX + 68),
         (centerY - 57),
         16,
         16), hint='')
        ic.state = uiconst.UI_HIDDEN
        ic.orgPos = ic.top
        ic.OnClick = self.OnGroupAllButtonClicked
        ic.OnMouseDown = self.OverloadRackBtnMouseDown
        ic.OnMouseUp = self.OverloadRackBtnMouseUp
        self.CheckGroupAllButton()



    def OnGroupAllButtonClicked(self, *args):
        if settings.user.ui.Get('lockModules', 0):
            return 
        stateMgr = sm.GetService('godma').GetStateManager()
        if stateMgr.CanGroupAll():
            stateMgr.LinkAllWeapons()
        else:
            stateMgr.UnlinkAllWeapons()



    def InitOverloadBtns(self, grid, shipmodules):
        w = self.sr.slotsContainer.width
        h = self.sr.slotsContainer.height
        centerX = ((w - 20) / 2)
        centerY = ((h - 20) / 2)
        par = uicls.Container(name='btnPar', width=20, height=20, align=uiconst.TOPLEFT, left=0, top=0, state=uiconst.UI_NORMAL)
        par.pickRadius = 8
        icon = uicls.Sprite(align=uiconst.TOALL, state=uiconst.UI_DISABLED)
        icon.texture.pixels = 'res:/UI/Texture/shipmodule.dds'
        icon.rectWidth = 20
        icon.rectHeight = 20
        icon.rectLeft = 64
        icon.rectTop = 64
        par.children.append(icon)
        overloadEffectsByRack = {}
        modulesByRack = {}
        for module in shipmodules:
            for key in module.effects.iterkeys():
                effect = module.effects[key]
                if (effect.effectID in (const.effectHiPower,
                 const.effectMedPower,
                 const.effectLoPower)):
                    if (effect.effectID not in modulesByRack):
                        modulesByRack[effect.effectID] = []
                    modulesByRack[effect.effectID].append(module)
                    for key in module.effects.iterkeys():
                        effect2 = module.effects[key]
                        if (effect2.effectCategory == const.dgmEffOverload):
                            if (effect.effectID not in overloadEffectsByRack):
                                overloadEffectsByRack[effect.effectID] = []
                            overloadEffectsByRack[effect.effectID].append(effect2)



        i = 0
        for each in ['Hi',
         'Med',
         'Lo']:
            (x, y,) = grid[i]
            par = uicls.Container(par.CopyTo())
            par.left = ((centerX + 67) + int((x * 14)))
            par.top = (centerY + int((y * 14)))
            par.children[0].rectLeft = (104 - (20 * i))
            par.OnClick = self.OverloadRackBtnClick
            par.OnMouseDown = self.OverloadRackBtnMouseDown
            par.OnMouseUp = self.OverloadRackBtnMouseUp
            par.OnMouseExit = self.OverloadRackBtnMouseExit
            par.orgPos = par.top
            par.active = False
            par.powerEffectID = getattr(const, ('effect%sPower' % each), None)
            par.activationID = None
            par.name = ('overloadBtn' + each)
            self.sr.slotsContainer.children.insert(0, par)
            i += 1

        self.CheckOverloadRackBtnState(shipmodules)



    def ToggleRackOverload(self, what):
        if ((what not in ('Hi', 'Med', 'Lo')) or self.sr.slotsContainer.destroyed):
            return 
        btn = uiutil.FindChild(self.sr.slotsContainer, ('overloadBtn' + what))
        if btn:
            if btn.activationID:
                uthread.new(self.OverloadRackBtnClick, btn)
            else:
                uthread.new(eve.Message, 'Disabled')



    def OverloadRackBtnClick(self, btn, *args):
        if settings.user.ui.Get('lockOverload', 0):
            eve.Message('error')
            eve.Message('LockedOverloadState')
            return 
        if btn.active:
            eve.Message('click')
            sm.GetService('godma').StopOverloadRack(btn.activationID)
        else:
            eve.Message('click')
            sm.GetService('godma').OverloadRack(btn.activationID)



    def OverloadRackBtnMouseDown(self, btn, *args):
        btn.top = (btn.orgPos + 1)



    def OverloadRackBtnMouseUp(self, btn, *args):
        btn.top = btn.orgPos



    def OverloadRackBtnMouseExit(self, btn, *args):
        btn.top = btn.orgPos



    def CheckOverloadRackBtnState(self, shipmodules = None):
        if self.assumingcontrol:
            return 
        if ((not self) or ((not hasattr(self, 'sr')) or (not self.sr.Get('slotsContainer')))):
            return 
        if self.checkingoverloadrackstate:
            self.checkingoverloadrackstate = 2
            return 
        self.checkingoverloadrackstate = 1
        if (shipmodules is None):
            ship = sm.GetService('godma').GetItem(eve.session.shipid)
            if (ship is None):
                return 
            shipmodules = ship.modules
        overloadEffectsByRack = {}
        modulesByRack = {}
        for module in shipmodules:
            for key in module.effects.iterkeys():
                effect = module.effects[key]
                if (effect.effectID in (const.effectHiPower,
                 const.effectMedPower,
                 const.effectLoPower)):
                    if (effect.effectID not in modulesByRack):
                        modulesByRack[effect.effectID] = []
                    modulesByRack[effect.effectID].append(module)
                    for key in module.effects.iterkeys():
                        effect2 = module.effects[key]
                        if (effect2.effectCategory == const.dgmEffOverload):
                            if (effect.effectID not in overloadEffectsByRack):
                                overloadEffectsByRack[effect.effectID] = []
                            overloadEffectsByRack[effect.effectID].append(effect2)



        i = 0
        for each in ['Hi',
         'Med',
         'Lo']:
            btn = uiutil.GetChild(self.sr.slotsContainer, ('overloadBtn' + each))
            btn.activationID = None
            btn.active = False
            btn.children[0].rectTop = 64
            btn.sr.hint = mls.UI_CMD_OVERLOADRACK
            btn.state = uix.UI_DISABLED
            if (btn.powerEffectID in modulesByRack):
                btn.activationID = modulesByRack[btn.powerEffectID][0].itemID
            if (btn.powerEffectID in overloadEffectsByRack):
                sumInactive = sum([ 1 for olEffect in overloadEffectsByRack[btn.powerEffectID] if not(olEffect.isActive) ])
                if not sumInactive:
                    btn.children[0].rectTop = 84
                    btn.active = True
                    btn.sr.hint = mls.UI_CMD_STOPOVERLOADRACK
            btn.state = uix.UI_NORMAL

        if (self.checkingoverloadrackstate == 2):
            self.checkingoverloadrackstate = 0
            return self.CheckOverloadRackBtnState(shipmodules)
        self.checkingoverloadrackstate = 0



    def CheckGroupAllButton(self):
        icon = uiutil.GetChild(self.sr.slotsContainer, 'groupAllIcon')
        stateMgr = sm.GetService('godma').GetStateManager()
        for (typeID, qty,) in stateMgr.GetGroupableTypes().iteritems():
            if (qty > 1):
                break
        else:
            icon.state = uiconst.UI_HIDDEN
            return 

        icon.state = uiconst.UI_NORMAL
        if stateMgr.CanGroupAll():
            icon.ChangeIcon(icon='ui_73_16_252')
            hint = mls.UI_CMD_GROUPALLWEAPONS
        else:
            icon.ChangeIcon(icon='ui_73_16_251')
            hint = mls.UI_CMD_UNGROUPALLWEAPONS
        if settings.user.ui.Get('lockModules', False):
            hint = (hint + (' (%s)' % mls.UI_GENERIC_LOCKED))
        icon.hint = hint
        if getattr(self, 'updateGroupAllButtonThread', None):
            self.updateGroupAllButtonThread.kill()
        self.updateGroupAllButtonThread = uthread.new(self.UpdateGroupAllButton)



    def UpdateGroupAllButton(self):
        if ((not self) or self.destroyed):
            return 
        GetOpacity = sm.GetService('godma').GetStateManager().GetGroupAllOpacity
        if sm.GetService('godma').GetStateManager().CanGroupAll():
            attributeName = 'lastGroupAllRequest'
        else:
            attributeName = 'lastUngroupAllRequest'
        icon = uiutil.GetChild(self.sr.slotsContainer, 'groupAllIcon')
        icon.state = uiconst.UI_DISABLED
        while True:
            opacity = GetOpacity(attributeName)
            if (opacity > 0.999):
                break
            icon.color.a = (0.2 + (opacity * 0.6))
            blue.pyos.synchro.Yield()
            if ((not self) or self.destroyed):
                return 

        icon.color.a = 1.0
        icon.state = uiconst.UI_NORMAL



    def CheckButtonVisibility(self, gidx, sTypes, totalslot, myOrder):
        totalslots = totalslot
        ship = sm.GetService('godma').GetItem(eve.session.shipid)
        lastType = ''
        showEmptySlots = settings.user.ui.Get('showEmptySlots', 0)
        totalHi = getattr(ship, 'hiSlots', 0)
        totalMed = getattr(ship, 'medSlots', 0)
        totalLow = getattr(ship, 'lowSlots', 0)
        slotUIID = 0
        for sType in sTypes:
            if (totalslot is None):
                totalslots = int(getattr(ship, sType, 0))
            ignoredSlots = 0
            for sidx in xrange(totalslots):
                if (sidx == 8):
                    break
                flagTypes = ['Hi',
                 'Med',
                 'Lo',
                 'Stuct']
                if not self.assumingcontrol:
                    if (gidx < len(flagTypes)):
                        slotFlag = getattr(const, ('flag%sSlot%s' % (flagTypes[gidx], sidx)), None)
                    slot = self.sr.slotsByFlag.get(slotFlag, None)
                else:
                    slotFlag = myOrder[sidx]
                    slot = self.sr.slotsByFlag.get(slotFlag, None)
                typeNames = ['High',
                 'Medium',
                 'Low',
                 'Stuct']
                slotUIID += 1
                if (gidx < len(typeNames)):
                    currType = typeNames[gidx]
                    if (currType != lastType):
                        slotUIID = 1
                    lastType = currType
                    if slot:
                        slot.name = ('inFlight%sSlot%s' % (typeNames[gidx], slotUIID))
                if (showEmptySlots and (not self.assumingcontrol)):
                    if (slot and ((slot.sr.module is None) and (slotFlag not in self.passiveFiltered))):
                        slot.showAsEmpty = 1
                        if self.assumingcontrol:
                            slot.sr.hint = mls.UI_INFLIGHT_EMPTYSTRUCTURECONTROLSLOT
                            slot.state = uix.UI_NORMAL
                        else:
                            if ((gidx == 0) and (ignoredSlots < self.totalSlaves)):
                                ignoredSlots += 1
                                slot.ignored = 1
                                continue
                    slot.sr.hint = [mls.UI_INFLIGHT_EMPTYHIGHSLOT,
                     mls.UI_INFLIGHT_EMPTYMEDIUMSLOT,
                     mls.UI_INFLIGHT_EMPTYLOWSLOT][gidx]
                    slot.state = uix.UI_NORMAL
                    iconpath = ['ui_08_64_11',
                     'ui_08_64_10',
                     'ui_08_64_09',
                     'ui_44_64_14'][gidx]
                    icon = uicls.Icon(icon=iconpath, parent=slot, pos=(13, 13, 24, 24), align=uiconst.TOPLEFT, state=uix.UI_DISABLED, idx=0, ignoreSize=True)
                    icon.left = ((slot.width - icon.width) / 2)
                    icon.color.a = 0.25
                    icon.tripass = eve.rot.GetInstance('res:/UI/Pass/linear.blue')
                else:
                    continue

            gidx += 1




    def _FitStructureSlot(self, moduleInfo, charges):
        showPassive = settings.user.ui.Get('showPassiveModules', 1)
        if (moduleInfo.categoryID != const.categoryStructure):
            return 
        if ((not showPassive) and (self.GetDefaultEffect(moduleInfo) is None)):
            self.passiveFiltered.append(moduleInfo.flagID)
            return 
        slot = self.sr.slotsByFlag.get(moduleInfo.itemID, None)
        if (slot is None):
            return 
        if (slot.sr.module is not None):
            return 
        self.FitStructureSlot(slot, moduleInfo, charges.get(moduleInfo.itemID, None))



    def _FitSlot(self, moduleInfo, charges, grey = 0, slotUIID = 'slot'):
        showPassive = settings.user.ui.Get('showPassiveModules', 1)
        if (moduleInfo.categoryID == const.categoryCharge):
            return 
        if ((not showPassive) and (self.GetDefaultEffect(moduleInfo) is None)):
            self.passiveFiltered.append(moduleInfo.flagID)
            return 
        slot = self.sr.slotsByFlag.get(moduleInfo.flagID, None)
        if (slot is None):
            return 
        if (slot.sr.module is not None):
            return 
        self.FitSlot(slot, moduleInfo, charges.get(moduleInfo.flagID, None), grey=grey, slotUIID=slotUIID)



    def GetDefaultEffect(self, moduleInfo):
        for key in moduleInfo.effects.iterkeys():
            effect = moduleInfo.effects[key]
            if self.IsEffectActivatible(effect):
                return effect




    def IsEffectActivatible(self, effect):
        return (effect.isDefault and ((effect.effectName != 'online') and (effect.effectCategory in (const.dgmEffActivation, const.dgmEffTarget))))



    def ResetSwapMode(self):
        for each in self.sr.slotsContainer.children:
            each.opacity = 1.0
            if (each.sr.get('module', -1) == -1):
                continue
            if (((each.sr.module is None) and (not getattr(each, 'showAsEmpty', 0))) or getattr(each, 'ignored', 0)):
                each.state = uix.UI_HIDDEN
            if getattr(each.sr, 'module', None):
                if getattr(each, 'linkDragging', None):
                    each.linkDragging = 0
                    each.sr.module.CheckOverload()
                    each.sr.module.CheckOnline()
                    each.sr.module.CheckMasterSlave()
                    each.sr.module.StopShowingGroupHighlight()
                    each.sr.module.CheckOnline()
                each.sr.module.blockClick = 0




    def StartDragMode(self, itemID, typeID):
        for each in self.sr.slotsContainer.children:
            if ((not hasattr(each, 'sr')) or (not hasattr(each.sr, 'module'))):
                continue
            if (each.name.startswith('overload') or (each.name == 'groupAllIcon')):
                continue
            if (each.sr.module is None):
                each.opacity = 0.7
            each.state = uiconst.UI_NORMAL
            if (typeID is None):
                continue
            if (getattr(each.sr, 'module', None) is not None):
                moduleType = each.sr.module.GetModuleType()
                godmaStateManager = sm.StartService('godma').GetStateManager()
                isGroupable = godmaStateManager.IsGroupable(each.sr.module.sr.moduleInfo.groupID)
                if isGroupable:
                    each.linkDragging = 1
                    if (each.sr.module.sr.moduleInfo.itemID == itemID):
                        each.sr.module.color.a = 0.2
                else:
                    if (moduleType and (moduleType[0] == typeID)):
                        each.sr.module.ShowGroupHighlight()
            else:
                continue




    def GetPosFromFlag(self, slotFlag):
        return self.sr.slotsByFlag[slotFlag].sr.slotPos



    def GetSlotOrder(self):
        defaultOrder = []
        for r in xrange(3):
            for i in xrange(8):
                slotFlag = getattr(const, ('flag%sSlot%s' % (['Hi',
                  'Med',
                  'Lo'][r], i)), None)
                if (slotFlag is not None):
                    defaultOrder.append(slotFlag)


        try:
            return settings.user.ui.Get('slotOrder', {}).get(eve.session.shipid, defaultOrder)
        except:
            log.LogException()
            sys.exc_clear()
            return defaultOrder



    def ChangeSlots(self, toFlag, fromFlag):
        toModule = self.GetModuleType(toFlag)
        fromModule = self.GetModuleType(fromFlag)
        shift = eve.triapp.uilib.Key(uix.VK_SHIFT)
        if (toModule and (fromModule and (toModule[0] == fromModule[0]))):
            self.LinkWeapons(toModule, fromModule, toFlag, fromFlag, merge=(not shift))
            if not sm.GetService('godma').GetStateManager().IsMasterModule(toModule[1]):
                self.SwapSlots(fromFlag, toFlag)
        else:
            self.SwapSlots(toFlag, fromFlag)



    def SwapSlots(self, slotFlag1, slotFlag2):
        module1 = self.GetModuleType(slotFlag1)
        module2 = self.GetModuleType(slotFlag2)
        shift = eve.triapp.uilib.Key(uix.VK_SHIFT)
        if (shift and ((module1 is None) and (module2 is not None))):
            stateMgr = sm.GetService('godma').GetStateManager()
            if stateMgr.IsInWeaponBank(module2[1]):
                moduleID = stateMgr.UnlinkModule(module2[1])
                slotFlag2 = stateMgr.GetItem(moduleID).flagID
        current = self.GetSlotOrder()[:]
        flag1Idx = current.index(slotFlag1)
        flag2Idx = current.index(slotFlag2)
        current[flag1Idx] = slotFlag2
        current[flag2Idx] = slotFlag1
        all = settings.user.ui.Get('slotOrder', {})
        all[eve.session.shipid] = current
        settings.user.ui.Set('slotOrder', all)
        self.InitSlots()



    def LinkWeapons(self, master, slave, slotFlag1, slotFlag2, merge = False):
        godmaStateManager = sm.StartService('godma').GetStateManager()
        groupID = cfg.invtypes.Get(master[0]).groupID
        areTurrets = godmaStateManager.IsGroupable(groupID)
        slaves = godmaStateManager.GetModulesSlaves(slave[1])
        swapSlots = 0
        if slaves:
            swapSlots = 1
        if not areTurrets:
            eve.Message('CustomNotify', {'notify': mls.UI_SHARED_WEAPONLINK_NOTTHISTYPE})
            return 
        weaponLinked = sm.GetService('godma').GetStateManager().LinkWeapons(master[1], slave[1], master[0], merge=merge)
        if (weaponLinked and swapSlots):
            self.SwapSlots(slotFlag1, slotFlag2)



    def GetModuleType(self, flag):
        if not self.sr.slotsByFlag.has_key(flag):
            return 
        else:
            module = self.sr.slotsByFlag[flag].sr.module
            if not module:
                return 
            return module.GetModuleType()



    def FitSlot(self, slot, moduleInfo, charge = None, grey = 0, slotUIID = 'slot'):
        p = uiutil.GetChild(slot, 'innerArea')
        pos = ((slot.width - 48) / 2)
        module = xtriui.ModuleButton(parent=p, align=uiconst.RELATIVE, width=48, height=48, top=pos, left=pos, idx=0, state=uiconst.UI_DISABLED)
        module.Setup(moduleInfo, grey=grey)
        self.sr.modules[moduleInfo.itemID] = module
        slot.sr.module = module
        slot.state = uix.UI_NORMAL
        slot.sr.shortcutHint.state = uix.UI_HIDDEN
        slot.name = slotUIID
        if charge:
            module.SetCharge(charge)
        if (moduleInfo.flagID in [const.flagHiSlot0,
         const.flagHiSlot1,
         const.flagHiSlot2,
         const.flagHiSlot3,
         const.flagHiSlot4,
         const.flagHiSlot5,
         const.flagHiSlot6,
         const.flagHiSlot7]):
            self.myHarpointFlags.append(moduleInfo.flagID)



    def FitStructureSlot(self, slot, moduleInfo, charge = None):
        pos = ((slot.width - 48) / 2)
        module = xtriui.DefenceStructureButton(uicls.Container(parent=slot, align=uiconst.TOPLEFT, width=64, height=250, top=0, left=0, idx=1, state=uix.UI_DISABLED))
        module.Setup(moduleInfo)
        self.sr.modules[moduleInfo.itemID] = module
        slot.sr.module = module
        slot.state = uix.UI_NORMAL
        if charge:
            module.SetCharge(charge)



    def AutoPilotOnOff(self, onoff, *args):
        if onoff:
            sm.GetService('autoPilot').SetOn()
        else:
            sm.GetService('autoPilot').SetOff('toggled by shipUI')



    def OnAutoPilotOn(self):
        uiutil.GetChild(self.sr.autopilotBtn, 'busy').state = uix.UI_DISABLED
        self.sr.autopilotBtn.sr.hint = mls.UI_CMD_DEACTIVATEAUTOPILOT
        self.sr.autopilotBtn.sr.hint += self._GetShortcutForCommand(self.sr.autopilotBtn.cmdName)



    def OnAutoPilotOff(self):
        uiutil.GetChild(self.sr.autopilotBtn, 'busy').state = uix.UI_HIDDEN
        self.sr.autopilotBtn.sr.hint = mls.UI_CMD_ACTIVATEAUTOPILOT
        self.sr.autopilotBtn.sr.hint += self._GetShortcutForCommand(self.sr.autopilotBtn.cmdName)



    def OnTacticalOverlayChange(self, isOn):
        activeIndicator = uiutil.GetChild(self.sr.tacticalBtn, 'busy')
        if isOn:
            activeIndicator.state = uiconst.UI_DISABLED
            self.sr.tacticalBtn.sr.hint = mls.UI_CMD_HIDETACTICALOVERLEY
        else:
            activeIndicator.state = uiconst.UI_HIDDEN
            self.sr.tacticalBtn.sr.hint = mls.UI_CMD_SHOWTACTICALOVERLEY



    def OnCloseView(self):
        sm.UnregisterNotify(self)
        settings.user.ui.Set('selected_shipuicateg', self.sr.selectedcateg)
        if self.cookie:
            sm.GetService('inv').Unregister(self.cookie)
            self.cookie = None



    def IsMine(self, rec):
        return ((rec.locationID == eve.session.shipid) and ((rec.categoryID == const.categoryModule) and (rec.flagID not in (const.flagCargo, const.flagDroneBay))))



    def OnInvChange(self, item, change):
        if (const.ixFlag in change):
            if (cfg.IsShipFittingFlag(item.flagID) or cfg.IsShipFittingFlag(change[const.ixFlag])):
                uicore.layer.shipui.CloseView()
                uicore.layer.shipui.OpenView()



    def DoBallRemove(self, ball, slimItem, terminal):
        if (ball is None):
            return 
        uix.LogInfo('DoBallRemove::shipui', ball.id)
        if ((self.ball is not None) and (ball.id == self.ball.id)):
            self.UnhookBall()
        uthread.new(self.UpdateJammersAfterBallRemoval, ball.id)



    def UpdateJammersAfterBallRemoval(self, ballID):
        jams = self.jammers.keys()
        checkJam = 0
        for jammingType in jams:
            jam = self.jammers[jammingType]
            for id in jam.keys():
                (sourceBallID, moduleID, targetBallID,) = id
                if (ballID == sourceBallID):
                    del self.jammers[jammingType][id]
                    checkJam = 1


        if checkJam:
            self.CheckJam()



    def DoBallClear(self, solItem):
        self.ball = None



    def ProcessShipEffect(self, godmaStm, effectState):
        statemanager = sm.StartService('godma').GetStateManager()
        masterID = statemanager.IsInWeaponBank(effectState.itemID)
        if masterID:
            module = self.GetModule(masterID)
        else:
            module = self.GetModule(effectState.itemID)
        if module:
            uthread.new(module.Update, effectState)
            uthread.new(self.CheckOverloadRackBtnState)
        if (effectState.error is not None):
            uthread.new(eve.Message, effectState.error[0], effectState.error[1])
        if (effectState.effectName == 'online'):
            self.UpdateGauges()



    def OnAttributes(self, ch):
        for each in ch:
            if (each[0] == 'isOnline'):
                self.CheckGroupAllButton()
            if (each[0] != 'damage'):
                continue
            (masterID, damage,) = sm.GetService('godma').GetStateManager().GetMaxDamagedModuleInGroup(each[1].itemID)
            module = self.GetModule(masterID)
            if (module is None):
                continue
            module.SetDamage((damage / module.sr.moduleInfo.hp))




    def ProcessRookieStateChange(self, state):
        if (eve.session.solarsystemid and self.sr.wnd):
            if not (not (eve.rookieState and (eve.rookieState < 21))):
                self.state = uix.UI_HIDDEN
            else:
                self.state = uix.UI_PICKCHILDREN
                self.InitButtons()



    def OnJamStart(self, sourceBallID, moduleID, targetBallID, jammingType, startTime, duration):
        if (jammingType not in self.jammers):
            self.jammers[jammingType] = {}
        self.jammers[jammingType][(sourceBallID,
         moduleID,
         targetBallID)] = (startTime, duration)
        self.CheckJam()



    def OnJamEnd(self, sourceBallID, moduleID, targetBallID, jammingType):
        if (jammingType in self.jammers):
            id = (sourceBallID,
             moduleID,
             targetBallID)
            if (id in self.jammers[jammingType]):
                del self.jammers[jammingType][id]
        self.CheckJam()



    def CheckJam(self):
        jams = self.jammers.keys()
        jams.sort()
        for jammingType in jams:
            jam = self.jammers[jammingType]
            sortList = []
            for id in jam.iterkeys():
                (sourceBallID, moduleID, targetBallID,) = id
                if (targetBallID == eve.session.shipid):
                    (startTime, duration,) = jam[id]
                    sortList.append(((startTime + duration), (sourceBallID,
                      moduleID,
                      targetBallID,
                      jammingType,
                      startTime,
                      duration)))

            if sortList:
                sortList = uiutil.SortListOfTuples(sortList)
                (sourceBallID, moduleID, targetBallID, jammingType, startTime, duration,) = sortList[-1]
                bracketName = sm.GetService('bracket').GetBracketName(sourceBallID)
                self.ShowTimer(jammingType, startTime, duration, ('%s<br>%s' % (bracketName, self.timerNames.get(jammingType, mls.UI_INFLIGHT_NAMELESS))))
            else:
                self.KillTimer(jammingType)




    def OnShipScanCompleted(self, shipID, capacitorCharge, capacitorCapacity, hardwareList):
        bp = sm.GetService('michelle').GetBallpark()
        if not bp:
            return 
        slimItem = bp.slimItems[shipID]
        wndName = ('%s %s' % (uix.GetSlimItemName(slimItem), mls.UI_INFLIGHT_SCANRESULT))
        wnd = sm.GetService('window').GetWindow(wndName, create=1, decoClass=form.ShipScan, maximize=1, shipID=shipID, windowPrefsID='shipScan')
        if wnd:
            wnd.LoadResult(capacitorCharge, capacitorCapacity, hardwareList)



    def OnCargoScanComplete(self, shipID, cargoList):
        bp = sm.GetService('michelle').GetBallpark()
        if not bp:
            return 
        slimItem = bp.slimItems[shipID]
        shipName = uix.GetSlimItemName(slimItem)
        header = (mls.UI_INFLIGHT_CARGOSCANRESULT2 % {'name': shipName,
         'num': len(cargoList)})
        scrolllist = []
        for (typeID, quantity,) in cargoList:
            scrolllist.append((('%s %s' % (quantity, cfg.invtypes.Get(typeID).name)),
             None,
             typeID))

        uix.ListWnd(scrolllist, 'item', header, isModal=0, minChoices=None)



    def OnModify(self, op, rec, change):
        t = uthread.new(self.OnModify_thread, op, rec, change)
        t.context = 'ShipUI::OnModify'



    def OnModify_thread(self, op, rec, change):
        lg.Info('shipui', 'OnModify', op, change, rec)
        if not rec:
            return 
        if (cfg.invtypes.Get(rec.typeID).categoryID != const.categoryCharge):
            lg.Warn('shipui', 'OnModify: not a charge?')
            return 
        haveThisCharge = 0
        for (flag, slot,) in self.sr.slotsByFlag.iteritems():
            if (slot and (slot.sr.module.charge and (slot.sr.module.charge.itemID == rec.itemID))):
                haveThisCharge = 1
                break

        slot = self.sr.slotsByFlag.get(rec.flagID, None)
        if (slot and slot.sr.module):
            if ((op == 'r') or (rec.stacksize == 0)):
                slot.sr.module.SetCharge(None)
            elif (slot.sr.module.charge and (slot.sr.module.charge.itemID and (slot.sr.module.charge.itemID != rec.itemID))):
                lg.Info('shipui', 'Residual update in parting missile-- ignoring')
            else:
                slot.sr.module.SetCharge(rec)
        elif haveThisCharge:
            self.sr.slotsByFlag[flag].SetCharge(None)



    def UnhookBall(self):
        self.ball = None



    def Init(self, ball):
        if (ball.id == self.initedshipid):
            self.ball = ball
            return 
        if self.initing:
            return 
        if (eve.session.shipid is None):
            self.CloseView()
            return 
        self.initing = 1
        self.initedshipid = eve.session.shipid
        self.capacity = None
        self.ball = ball
        ship = sm.GetService('godma').GetItem(eve.session.shipid)
        if (ship is None):
            raise RuntimeError('ShipUI being inited with no ship state!')
        self.InitSpeed()
        uthread.new(self.UpdateGauges)
        if ((not (eve.rookieState and (eve.rookieState < 21))) and (not sm.GetService('planetUI').IsOpen())):
            self.state = uix.UI_PICKCHILDREN
        self.InitSlots()
        self.initing = 0
        if ((not sm.GetService('map').IsOpen()) and (not sm.GetService('planetUI').IsOpen())):
            uix.GetInflightNav()
        self.invReady = 1



    def InitSpeed(self):
        if self.speedInited:
            return 
        for btnname in ['stopButton', 'maxspeedButton']:
            newBtn = xtriui.SlimDeco(uiutil.GetChild(self.sr.wnd, btnname))
            newBtn.LoadEvents(['Click',
             'MouseMove',
             'MouseEnter',
             'MouseExit'])
            newBtn.OnClick = self.ClickSpeedBtn
            if (btnname == 'maxspeedButton'):
                newBtn.sr.hint = (((mls.UI_INFLIGHT_SETFULLSPEED + ' (') + self.FormatSpeed(self.ball.maxVelocity)) + ')')
                newBtn.OnMouseEnter = self.CheckSpeedHint
            else:
                newBtn.sr.hint = mls.UI_INFLIGHT_STOPTHESHIP
            self.sr.Set(btnname, newBtn)

        self.sr.speedGauge = uiutil.GetChild(self.sr.wnd, 'speedNeedle')
        self.sr.speedGaugeParent = xtriui.SlimDeco(uiutil.GetChild(self.sr.wnd, 'speedGaugeParent'))
        self.sr.speedGaugeParent.LoadEvents(['Click',
         'MouseEnter',
         'MouseMove',
         'MouseExit'])
        self.sr.speedGaugeParent.OnClick = self.ClickSpeedoMeter
        self.sr.speedGaugeParent.OnMouseMove = self.CheckSpeedHint
        self.sr.speedStatus = uicls.Label(text='', parent=self.sr.speedGaugeParent.parent.parent, left=0, top=127, color=(0.0, 0.0, 0.0, 1.0), width=100, autowidth=False, letterspace=1, fontsize=9, state=uiconst.UI_DISABLED, uppercase=1, idx=0, shadow=None, align=uiconst.CENTERTOP)
        self.sr.speedGaugeFill = uiutil.GetChild(self.sr.wnd, 'speedGaugeFill')
        self.speedInited = 1
        uthread.new(self.SetSpeed, self.ball.speedFraction, initing=1)
        self.sr.speedtimer = base.AutoTimer(133, self.UpdateSpeed)



    def ClickSpeedBtn(self, btn, *args):
        if (eve.rookieState and (eve.rookieState < 22)):
            return 
        if (btn.name == 'stopButton'):
            self.StopShip()
        elif (btn.name == 'maxspeedButton'):
            bp = sm.GetService('michelle').GetBallpark()
            rbp = sm.GetService('michelle').GetRemotePark()
            if bp:
                ownBall = bp.GetBall(eve.session.shipid)
                if (ownBall and ((rbp is not None) and (ownBall.mode == destiny.DSTBALL_STOP))):
                    if not sm.GetService('autoPilot').GetState():
                        direction = trinity.TriVector(0.0, 0.0, -1.0)
                        currentDirection = self.ball.GetQuaternionAt(blue.os.GetTime())
                        direction.TransformQuaternion(currentDirection)
                        rbp.GotoDirection(direction.x, direction.y, direction.z)
            if (rbp is not None):
                rbp.SetSpeedFraction(1.0)
                sm.GetService('logger').AddText(('%s %s' % (mls.UI_INFLIGHT_SPEEDCHANGEDTO, self.FormatSpeed(self.ball.maxVelocity))), 'notify')
                sm.GetService('gameui').Say(('%s %s' % (mls.UI_INFLIGHT_SPEEDCHANGEDTO, self.FormatSpeed(self.ball.maxVelocity))))
                self.wantedspeed = 1.0
            else:
                self.wantedspeed = None



    def GetSpeedPortion(self):
        w = self.sr.wnd
        (l, t, w, h,) = self.sr.wnd.GetAbsolute()
        centerX = (l + (w / 2))
        centerY = (t + (h / 2))
        y = float((eve.triapp.uilib.y - centerY))
        x = float((eve.triapp.uilib.x - centerX))
        if (x and y):
            angle = math.atan((x / y))
            deg = ((angle / math.pi) * 180.0)
            factor = ((45.0 + deg) / 90.0)
            if (factor < 0.05):
                return 0.0
            else:
                if (factor > 0.95):
                    return 1.0
                return factor
        return 0.5



    def ClickSpeedoMeter(self, sm, *args):
        uthread.new(self.SetSpeed, self.GetSpeedPortion())



    def CheckSpeedHint(self, *args):
        if not self.ball:
            return 
        mo = eve.triapp.uilib.mouseOver
        ms = self.sr.Get('maxspeedButton')
        if (mo == self.sr.speedGaugeParent):
            portion = self.GetSpeedPortion()
            parent = self.sr.speedGaugeParent
            speed = self.ball.GetVectorDotAt(blue.os.GetTime()).Length()
            if (self.ball.mode == destiny.DSTBALL_WARP):
                hint = ('%s: %s/%s' % (mls.UI_INFLIGHT_CURRENTSPEED,
                 util.FmtDist(speed, 2),
                 mls.UI_GENERIC_SECONDVERYSHORT))
                hint += ('<br>%s' % mls.UI_INFLIGHT_CANNOTCHANGESPEEDWHILEWARPING)
            else:
                fmtSpeed = self.FormatSpeed(speed)
                hint = ('%s: %s' % (mls.UI_INFLIGHT_CURRENTSPEED, fmtSpeed))
                hint += ('<br>%s %s' % (mls.UI_INFLIGHT_CLICKTOSETSPEEDTO, self.FormatSpeed((portion * self.ball.maxVelocity))))
            parent.sr.hint = hint
            uicore.UpdateHint(parent)
        elif (ms and ((not ms.destroyed) and (mo == ms))):
            ms.sr.hint = (((mls.UI_INFLIGHT_SETFULLSPEED + ' (') + self.FormatSpeed(self.ball.maxVelocity)) + ')')
            uicore.UpdateHint(ms)



    def FormatSpeed(self, speed):
        if (speed < 100):
            return ('%.1f %s' % (speed, mls.UI_GENERIC_MPERS))
        else:
            return ('%i %s' % (long(speed), mls.UI_GENERIC_MPERS))



    def InitCapacitor(self, maxcap):
        self.capacitorDone = 0
        self.capacity = float(maxcap)
        if (self.sr.powercore is None):
            return 
        uix.FlushList(self.sr.powercore.children[:-1])
        uix.FlushList(self.sr.powercore.children[0].children[:-1])
        numcol = min(18, int((maxcap / 50)))
        rotstep = (360.0 / max(1, numcol))
        self.sr.powercolumn.width = max(12, min(16, (numcol and int((192 / numcol)))))
        self.sr.powercolumn.state = uix.UI_DISABLED
        cell = self.sr.powercolumn.children[0]
        for i in xrange(4):
            newcell = cell.CopyTo()
            newcell.width -= 2
            newcell.top += (newcell.height - 2)
            self.sr.powercolumn.children.insert(0, newcell)
            cell = newcell

        for i in range(1, numcol):
            col = self.sr.powercolumn.CopyTo()
            col.transform.RotationZ(mathUtil.DegToRad((i * -rotstep)))
            self.sr.powercore.children.insert(0, col)

        self.capacitorDone = 1



    def GetModuleForFKey(self, key):
        slot = int(key[1:])
        gidx = ((slot - 1) / 8)
        sidx = ((slot - 1) % 8)
        slot = self.sr.slotsByOrder.get((gidx, sidx), None)
        if (slot and (slot.sr.module and (slot.sr.module.state == uix.UI_NORMAL))):
            return slot.sr.module



    def GetModule(self, moduleID):
        return self.sr.modules.get(moduleID, None)



    def Hide(self):
        self.state = uix.UI_HIDDEN



    def Show(self):
        if not (eve.rookieState and (eve.rookieState < 21)):
            self.state = uix.UI_PICKCHILDREN



    def OnMouseEnter(self, *args):
        if uix.GetInflightNav(0):
            uix.GetInflightNav(0).HideTargetingCursor()



    def FormatReadoutValue(self, portion, total):
        if settings.user.ui.Get('readoutType', 1):
            if (total == 0):
                return '0.0%'
            else:
                return ('%s%%' % util.FmtAmt(((portion / total) * 100.0), showFraction=1))
            return ('%s/%s' % (util.FmtAmt(portion, showFraction=1), util.FmtAmt(total, showFraction=1)))



    def GetMenu(self):
        if not hasattr(eve.session, 'shipid'):
            return []
        else:
            return sm.GetService('menu').CelestialMenu(eve.session.shipid)



    def UpdateCargoCapacity(self):
        if self.updatingcargo:
            return 
        self.updatingcargo = 1
        ship = sm.GetService('godma').GetItem(eve.session.shipid)
        if not ship:
            self.updatingcargo = 0
            return 
        cargo = None
        try:
            cargo = ship.GetCapacity()
        except RuntimeError, e:
            if (e.args[0] == 'GetItem: Item not here'):
                sys.exc_clear()
                uix.LogWarn('ShipUI: Checking cargo capacity failed > (GetItem: Item not here)')
                self.updatingcargo = 0
                return 
            raise e
        if (cargo and cargo.capacity):
            self.UpdateButtonGauge('cargo', (cargo.used / cargo.capacity), ('%s: %s' % (mls.UI_INFLIGHT_CARGOHOLDSTATUS, self.FormatReadoutValue((cargo.capacity and cargo.used), (cargo.capacity or 1)))))
        self.updatingcargo = 0



    def UpdateButtonGauge(self, what, portion, hint = ''):
        gauge = self.sr.Get(('gauge' + what), None)
        if not gauge:
            return 
        steps = 17
        pixels = int((102 * (1.0 - portion)))
        pixels = (pixels + (6 - (pixels % 6)))
        gauge.control.model.areas[0].areaTextures[0].translation.x = (pixels / 256.0)
        gauge.state = uix.UI_NORMAL
        gauge.hint = hint



    def UpdateGauges(self):
        if (getattr(self, 'updatingGauges', 0) or ((not self) or self.destroyed)):
            return 
        self.updatingGauges = 1
        ship = sm.GetService('godma').GetItem(eve.session.shipid)
        if not ship:
            self.sr.gaugetimer = None
            return 
        if ((not self) or self.destroyed):
            return 
        if not hasattr(self, 'capacity'):
            return 
        maxcap = ship.capacitorCapacity
        if (self.capacity != maxcap):
            self.InitCapacitor(maxcap)
        self.SetPower(ship.charge, float(maxcap))
        structure = max(0.0, min(1.0, float(('%.2f' % (1.0 - (ship.damage / ship.hp))))))
        lastStructure = getattr(self, 'lastStructure', 0.0)
        armor = 0.0
        if (ship.armorHP != 0):
            armor = max(0.0, min(1.0, float(('%.2f' % (1.0 - (ship.armorDamage / ship.armorHP))))))
        lastArmor = getattr(self, 'lastArmor', 0.0)
        shield = 0.0
        if (ship.shieldCapacity != 0):
            shield = max(0.0, min(1.0, float(('%.2f' % (ship.shieldCharge / ship.shieldCapacity)))))
        lastShield = getattr(self, 'lastShield', 0.0)
        lastLowHeat = getattr(self, 'lastLowHeat', 0.0)
        lastMedHeat = getattr(self, 'lastMedHeat', 0.0)
        lastHiHeat = getattr(self, 'lastHiHeat', 0.0)
        heatLow = (ship.heatLow / ship.heatCapacityLow)
        heatMed = (ship.heatMed / ship.heatCapacityMed)
        heatHi = (ship.heatHi / ship.heatCapacityHi)
        try:
            self.sr.structureGauge.sr.hint = (mls.UI_INFLIGHT_STRUCTURESTATUS % {'portion': (structure * 100),
             'left': max(0, (ship.hp - ship.damage)),
             'max': ship.hp})
            self.sr.armorGauge.sr.hint = (mls.UI_INFLIGHT_ARMORSTATUS % {'portion': (armor * 100),
             'left': max(0, (ship.armorHP - ship.armorDamage)),
             'max': ship.armorHP})
            self.sr.shieldGauge.sr.hint = (mls.UI_INFLIGHT_SHIELDSTATUS % {'portion': (shield * 100),
             'left': ship.shieldCharge,
             'max': ship.shieldCapacity})
            self.sr.heatPick.sr.hint = (mls.UI_INFLIGHT_HEATSTATUS % {'low': (heatLow * 100),
             'med': (heatMed * 100),
             'high': (heatHi * 100)})
            mo = eve.triapp.uilib.mouseOver
            if (mo in (self.sr.structureGauge,
             self.sr.armorGauge,
             self.sr.shieldGauge,
             self.sr.powercore)):
                uicore.UpdateHint(mo)
            if (self.sr.gaugeReadout and (self.sr.gaugeReadout.state != uix.UI_HIDDEN)):
                if settings.user.ui.Get('readoutType', 1):
                    self.sr.gaugeReadout.sr.Get('shield').text = ('%s: %s%%' % (mls.UI_GENERIC_SHIELD, util.FmtAmt((shield * 100), showFraction=0)))
                    self.sr.gaugeReadout.sr.Get('armor').text = ('%s: %s%%' % (mls.UI_GENERIC_ARMOR, util.FmtAmt((armor * 100), showFraction=0)))
                    self.sr.gaugeReadout.sr.Get('structure').text = ('%s: %s%%' % (mls.UI_GENERIC_STRUCTURE, util.FmtAmt((structure * 100), showFraction=0)))
                else:
                    self.sr.gaugeReadout.sr.Get('shield').text = ('%s: %s/%s' % (mls.UI_GENERIC_SHIELD,
                     util.FmtAmt(ship.shieldCharge, showFraction=1),
                     util.FmtAmt(ship.shieldCapacity, showFraction=1)))
                    self.sr.gaugeReadout.sr.Get('armor').text = ('%s: %s/%s' % (mls.UI_GENERIC_ARMOR,
                     util.FmtAmt(max(0, (ship.armorHP - ship.armorDamage)), showFraction=1),
                     util.FmtAmt(ship.armorHP, showFraction=1)))
                    self.sr.gaugeReadout.sr.Get('structure').text = ('%s: %s/%s' % (mls.UI_GENERIC_STRUCTURE,
                     util.FmtAmt(max(0, (ship.hp - ship.damage)), showFraction=1),
                     util.FmtAmt(ship.hp, showFraction=1)))
            props = [(lastStructure,
              structure,
              self.sr.structureGauge,
              None,
              1),
             (lastArmor,
              armor,
              self.sr.armorGauge,
              None,
              1),
             (lastShield,
              shield,
              self.sr.shieldGauge,
              None,
              1),
             (lastLowHeat,
              heatLow,
              self.sr.lowHeatGauge,
              None,
              2),
             (lastMedHeat,
              heatMed,
              self.sr.medHeatGauge,
              None,
              3),
             (lastHiHeat,
              heatHi,
              self.sr.hiHeatGauge,
              None,
              4)]
        except Exception, e:
            uix.LogWarn(e)
            sys.exc_clear()
            return 
        (start, ndt,) = (blue.os.GetTime(), 0.0)
        while (ndt != 1.0):
            ndt = max(ndt, min((blue.os.TimeDiffInMs(start) / 500.0), 1.0))
            for (lastval, newval, gauge, text, gaugeflag,) in props:
                if ((gauge is None) or gauge.destroyed):
                    return 
                lerped = mathUtil.Lerp(lastval, newval, ndt)
                if text:
                    text.text = ('<center>%d%%' % (lerped * 100))
                if (gaugeflag == 1):
                    rot = mathUtil.DegToRad(-(180 * lerped))
                    gauge.control.model.areas[0].areaTextures[0].rotation.SetYawPitchRoll(0.0, 0.0, rot)
                if (gaugeflag == 2):
                    gauge.transform.RotationZ(mathUtil.DegToRad((-2.0 - (56.0 * lerped))))
                    self.UpdateHeatGauge('Low', lerped)
                elif (gaugeflag == 3):
                    gauge.transform.RotationZ(mathUtil.DegToRad((-62.0 - (56.0 * lerped))))
                    self.UpdateHeatGauge('Med', lerped)
                else:
                    if (gaugeflag == 4):
                        gauge.transform.RotationZ(mathUtil.DegToRad((-122.0 - (56.0 * lerped))))
                        self.UpdateHeatGauge('Hi', lerped)

            blue.pyos.synchro.Yield()

        self.lastStructure = structure
        self.lastArmor = armor
        self.lastShield = shield
        self.lastLowHeat = heatLow
        self.lastMedHeat = heatMed
        self.lastHiHeat = heatHi
        if ((not self.sr.gaugetimer) and hasattr(self, 'UpdateGauges')):
            self.sr.gaugetimer = base.AutoTimer(500, self.UpdateGauges)
        self.updatingGauges = 0



    def UpdateHeatGauge(self, what, val):
        props = {'Low': [(0, 0),
                 (0, 38),
                 (0, 76),
                 (27, 0),
                 (27, 38)],
         'Med': [(83, 38),
                 (83, 56),
                 (83, 74),
                 (83, 92),
                 (83, 110)],
         'Hi': [(28, 77),
                (55, 0),
                (55, 38),
                (55, 76),
                (83, 0)]}
        if (what not in props):
            return 
        coords = props[what]
        if (val <= 0.125):
            idx = 0
        elif (val <= 0.375):
            idx = 1
        elif (val <= 0.625):
            idx = 2
        elif (val <= 0.875):
            idx = 3
        else:
            idx = 4
        (left, top,) = coords[idx]
        sprite = self.sr.Get(('heat%sUnderlay' % what))
        sprite.rectLeft = left
        sprite.rectTop = top



    def UpdateSpeed(self):
        if self.updatingspeed:
            return 
        self.updatingspeed = 1
        scene = sm.GetService('sceneManager').GetRegisteredScene('default')
        if ((scene is None) or (scene.ballpark is None)):
            self.updatingspeed = 0
            return 
        if (self.ball and (self.ball.ballpark and (self.sr.speedGauge and (not self.sr.speedGauge.destroyed)))):
            speed = self.ball.GetVectorDotAt(blue.os.GetTime()).Length()
            try:
                realSpeed = max(0.0, min(1.0, (speed / self.ball.maxVelocity)))
            except:
                sys.exc_clear()
                realSpeed = 0.0
        else:
            self.updatingspeed = 0
            return 
        speedGauge = self.sr.speedGauge
        speedGaugeFill = self.sr.speedGaugeFill
        lastSpeed = getattr(self, 'lastSpeed', None)
        currentFillRot = speedGaugeFill.control.model.areas[0].areaTextures[0].rotation.GetYawPitchRoll()[2]
        degRot = (90.0 * realSpeed)
        fillRot = mathUtil.DegToRad((-45.0 + degRot))
        if (lastSpeed != speed):
            speedGauge.transform.RotationZ(mathUtil.DegToRad((45.0 + degRot)))
            speedGaugeFill.control.model.areas[0].areaTextures[0].rotation.SetYawPitchRoll(0.0, 0.0, fillRot)
            if not (self.ball and self.ball.ballpark):
                return 
            if (self.ball.mode == destiny.DSTBALL_WARP):
                fmtSpeed = ('<center>(%s)' % mls.UI_INFLIGHT_WARPING)
            else:
                fmtSpeed = ('<center>' + self.FormatSpeed(speed))
            if (self.sr.speedStatus.text != fmtSpeed):
                self.sr.speedStatus.text = fmtSpeed
            self.CheckSpeedHint()
            if (self.sr.speedtimer and (self.sr.speedtimer.interval != 66)):
                self.sr.speedtimer.interval = 66
            self.lastSpeed = speed
        elif (self.sr.speedtimer and (self.sr.speedtimer.interval != 133)):
            self.sr.speedtimer.interval = 133
        self.updatingspeed = 0



    def StopShip(self, *args):
        uicore.cmd.CmdStopShip()
        self.wantedspeed = 0.0



    def SetSpeed(self, speed, initing = 0):
        if ((not self) or self.destroyed):
            return 
        if (eve.rookieState and (eve.rookieState < 22)):
            return 
        if (((not self.ball) or (self.ball.mode == destiny.DSTBALL_WARP)) and (speed > 0)):
            return 
        if (self.ball and (self.ball.ballpark is None)):
            self.UnhookBall()
            return 
        if ((not initing) and ((self.wantedspeed is not None) and (int((self.ball.speedFraction * 1000)) == int((speed * 1000)) == int((self.wantedspeed * 1000)) and (speed > 0)))):
            return 
        if (speed <= 0.0):
            self.StopShip()
        elif (speed != self.wantedspeed):
            rbp = sm.GetService('michelle').GetRemotePark()
            bp = sm.GetService('michelle').GetBallpark()
            if (bp and (not initing)):
                ownBall = bp.GetBall(eve.session.shipid)
                if (ownBall and ((rbp is not None) and (ownBall.mode == destiny.DSTBALL_STOP))):
                    if not sm.GetService('autoPilot').GetState():
                        direction = trinity.TriVector(0.0, 0.0, -1.0)
                        currentDirection = self.ball.GetQuaternionAt(blue.os.GetTime())
                        direction.TransformQuaternion(currentDirection)
                        rbp.GotoDirection(direction.x, direction.y, direction.z)
            if (rbp is not None):
                rbp.SetSpeedFraction(min(1.0, speed))
                if ((not initing) and self.ball):
                    sm.GetService('logger').AddText(('%s %s' % (mls.UI_INFLIGHT_SPEEDCHANGEDTO, self.FormatSpeed((speed * self.ball.maxVelocity)))), 'notify')
                    sm.GetService('gameui').Say(('%s %s' % (mls.UI_INFLIGHT_SPEEDCHANGEDTO, self.FormatSpeed((speed * self.ball.maxVelocity)))))
        if not initing:
            self.wantedspeed = max(speed, 0.0)
        if not self.sr.speedtimer:
            self.sr.speedtimer = base.AutoTimer(133, self.UpdateSpeed)



    def SetPower(self, load, maxcap):
        if ((not self) or ((not self.sr.powercore) or self.sr.powercore.destroyed)):
            return 
        if (self.capacity is not None):
            portion = (self.capacity * max(0.0, min(1.0, ((maxcap and float((load / maxcap))) or maxcap))))
            if portion:
                if (self.sr.powercore and (not self.sr.powercore.destroyed)):
                    self.sr.powercore.sr.hint = (mls.UI_INFLIGHT_CAPACITORSTATUS % {'portion': ((portion / self.capacity) * 100),
                     'left': portion,
                     'max': self.capacity})
        proportion = max(0.0, min(1.0, float(('%.2f' % ((maxcap and (load / maxcap)) or maxcap)))))
        if (self.lastsetcapacitor == proportion):
            return 
        sm.ScatterEvent('OnCapacitorChange', load, maxcap, proportion)
        good = trinity.TriColor((240 / 256.0), (90 / 256.0), (50.0 / 256.0))
        bad = trinity.TriColor((70 / 256.0), (26 / 256.0), (13.0 / 256.0))
        bad.Scale((1.0 - proportion))
        good.Scale(proportion)
        powerunits = [ unit for col in self.sr.powercore.children for unit in col.children if (unit.name != 'powerblink') ]
        if ((self.capacity is not None) and (self.capacitorDone and (powerunits and (len(powerunits) and (self is not None))))):
            visible = max(0, min(len(powerunits), int((proportion * len(powerunits)))))
            for each in powerunits[visible:]:
                if ((each is not None) and (not each.destroyed)):
                    each.tripass.textureStage0.customColor.SetRGB(0.25, 0.25, 0.25, 0.75)

            for each in powerunits[:visible]:
                if ((each is not None) and (not each.destroyed)):
                    each.tripass.textureStage0.customColor.SetRGB((bad.r + good.r), (bad.g + good.g), (bad.b + good.b), 1.0)

            if (self.sr.powerblink is None):
                self.sr.powerblink = blue.os.LoadObject('res:/UI/Component/selection_glow.blue')
                self.sr.powerblink.autoPos = uix.AUTOPOSXCENTER
                self.sr.powerblink.align = uix.UI_ALNONE
                self.sr.powerblink.left = 0
                self.sr.powerblink.name = 'powerblink'
                r = self.sr.powerblink.tripass.textureStage0.customColor.r
                g = self.sr.powerblink.tripass.textureStage0.customColor.g
                b = self.sr.powerblink.tripass.textureStage0.customColor.b
                sm.GetService('ui').BlinkSpriteRGB(self.sr.powerblink, r, g, b, 750, None, passColor=1)
            if ((visible != 0) and (visible < len(powerunits))):
                active = powerunits[(visible - 1)]
                uiutil.Transplant(self.sr.powerblink, active.parent, 0)
                self.sr.powerblink.state = uix.UI_DISABLED
                self.sr.powerblink.top = (active.top - 2)
                self.sr.powerblink.width = (active.width + 6)
                self.sr.powerblink.height = (active.height + 4)
            else:
                self.sr.powerblink.state = uix.UI_HIDDEN
            self.lastsetcapacitor = proportion



    def OnF(self, sidx, gidx):
        slot = self.sr.slotsByOrder.get((gidx, sidx), None)
        if (slot and (slot.sr.module and (slot.sr.module.state == uix.UI_NORMAL))):
            uthread.new(slot.sr.module.Click)
        else:
            uthread.new(eve.Message, 'Disabled')



    def OnFKeyOverload(self, sidx, gidx):
        slot = self.sr.slotsByOrder.get((gidx, sidx), None)
        if (slot and (slot.sr.module and (slot.sr.module.state == uix.UI_NORMAL))):
            if hasattr(slot.sr.module, 'ToggleOverload'):
                uthread.new(slot.sr.module.ToggleOverload)
        else:
            uthread.new(eve.Message, 'Disabled')



    def OnReloadAmmo(self):
        modulesByCharge = {}
        for module in self.sr.modules.itervalues():
            if not cfg.IsChargeCompatible(module.sr.moduleInfo):
                continue
            (chargeTypeID, chargeQuantity, roomForReload,) = module.GetChargeReloadInfo()
            if (chargeTypeID in modulesByCharge):
                modulesByCharge[chargeTypeID].append(module)
            else:
                modulesByCharge[chargeTypeID] = [module]

        for (chargeTypeID, modules,) in modulesByCharge.iteritems():
            ammoList = {}
            for item in module.GetMatchingAmmo(modules[0].sr.moduleInfo.typeID, 1):
                if ((item.typeID == chargeTypeID) and item.stacksize):
                    ammoList[item.itemID] = item.stacksize

            for module in modules:
                maxItemID = 0
                (chargeTypeID, chargeQuantity, roomForReload,) = module.GetChargeReloadInfo()
                bestItemID = None
                for (itemID, quant,) in ammoList.iteritems():
                    if (quant >= roomForReload):
                        if ((not bestItemID) or (quant < ammoList[bestItemID])):
                            bestItemID = itemID
                    if ((not maxItemID) or (quant > ammoList[maxItemID])):
                        maxItemID = itemID

                bestItemID = (bestItemID or maxItemID)
                if bestItemID:
                    quant = min(roomForReload, ammoList[maxItemID])
                    uthread.new(module.AutoReload, 1, bestItemID, quant)
                    ammoList[bestItemID] -= quant






class Slot(uicls.Container):
    __guid__ = 'xtriui.Slot'

    def OnDropData(self, dragObj, nodes):
        flag1 = self.sr.slotFlag
        for node in nodes:
            decoClass = node.Get('__guid__', None)
            if (decoClass == 'xtriui.ShipUIModule'):
                flag2 = node.slotFlag
                if (flag2 is not None):
                    uicore.layer.shipui.SwapSlots(flag1, node.slotFlag)
                break
            else:
                if (decoClass in ('xtriui.InvItem', 'listentry.InvItem')):
                    item = node.rec
                    if ((item.flagID == const.flagCargo) and (item.categoryID == const.categoryModule)):
                        eve.GetInventoryFromId(eve.session.shipid).Add(item.itemID, item.locationID, qty=None, flag=flag1)
                    break





class SpaceLayer(uicls.LayerCore):
    __guid__ = 'form.SpaceLayer'

    def OnCloseView(self):
        sm.GetService('tactical').CleanUp()
        sm.GetService('target').CleanUp()
        sm.GetService('bracket').CleanUp()



    def OnOpenView(self):
        return 




class NotifySettingsWindow(uicls.Window):
    __guid__ = 'form.NotifySettingsWindow'

    def ApplyAttributes(self, attributes):
        uicls.Window.ApplyAttributes(self, attributes)
        self.SetWndIcon(None)
        self.SetTopparentHeight(0)
        self.SetCaption(mls.UI_GENERIC_NOTIFYSETTINGS)
        self.SetMinSize([320, 120])
        self.MakeUnResizeable()
        self.SetupUi()



    def SetupUi(self):
        notifydata = [{'checkboxLabel': mls.UI_GENERIC_NOTIFY_SHIELD,
          'checkboxName': 'shieldNotification',
          'checkboxSetting': 'shieldNotificationEnabled',
          'checkboxDefault': 1,
          'sliderName': 'shield',
          'sliderSetting': ('shieldThreshold',
                            ('user', 'notifications'),
                            const.defaultShieldThreshold)},
         {'checkboxLabel': mls.UI_GENERIC_NOTIFY_ARMOUR,
          'checkboxName': 'armourNotification',
          'checkboxSetting': 'armourNotificationEnabled',
          'checkboxDefault': 1,
          'sliderName': 'armour',
          'sliderSetting': ('armourThreshold',
                            ('user', 'notifications'),
                            const.defaultArmourThreshold)},
         {'checkboxLabel': mls.UI_GENERIC_NOTIFY_HULL,
          'checkboxName': 'hullNotification',
          'checkboxDefault': 1,
          'checkboxSetting': 'hullNotificationEnabled',
          'sliderName': 'hull',
          'sliderSetting': ('hullThreshold',
                            ('user', 'notifications'),
                            const.defaultHullThreshold)}]
        labelWidth = 150
        mainContainer = uicls.Container(name='mainContainer', parent=self.sr.main, align=uiconst.TOALL)
        for each in notifydata:
            notifytop = uicls.Container(name='notifytop', parent=mainContainer, align=uiconst.TOTOP, pos=(const.defaultPadding,
             const.defaultPadding,
             0,
             26))
            uicls.Checkbox(text=each['checkboxLabel'], parent=notifytop, configName=each['checkboxSetting'], retval=None, prefstype=('user', 'notifications'), checked=settings.user.notifications.Get(each['checkboxSetting'], each['checkboxDefault']), callback=self.CheckBoxChange, align=uiconst.TOLEFT, pos=(const.defaultPadding,
             0,
             labelWidth,
             0))
            _par = uicls.Container(name=(each['sliderName'] + '_slider'), align=uiconst.TORIGHT, width=labelWidth, parent=notifytop, pos=(10, 0, 160, 0))
            par = uicls.Container(name=(each['sliderName'] + '_slider_sub'), align=uiconst.TOTOP, parent=_par, pos=(0,
             const.defaultPadding,
             0,
             8))
            slider = xtriui.Slider(blue.os.LoadObject('res:/UI/Component/slider.blue'))
            par.children.append(slider)
            slider.SetHandle(blue.os.LoadObject('res:/UI/Component/diode_handle.blue'), 12, 12)
            slider.SetUnderlay(blue.os.LoadObject('res:/UI/Component/frame_bumped.blue'), -1, 1)
            lbl = uicls.Label(text='', parent=_par, align=uiconst.TOTOP, name='label', state=uiconst.UI_PICKCHILDREN, width=labelWidth, left=const.defaultPadding, top=(1 + const.defaultPadding), fontsize=9, letterspace=2, tabs=[(labelWidth - 22)], uppercase=1, autowidth=False)
            lbl._tabMargin = 2
            slider.label = lbl
            slider.Startup(each['sliderName'], 0.0, 1.0, each['sliderSetting'], mls.UI_GENERIC_THRESHOLD)




    def CheckBoxChange(self, checkbox):
        if (checkbox.name == 'shieldNotification'):
            settings.user.notifications.Set('shieldNotificationEnabled', checkbox.checked)
        elif (checkbox.name == 'armourNotification'):
            settings.user.notifications.Set('armourNotificationEnabled', checkbox.checked)
        elif (checkbox.name == 'hullNotification'):
            settings.user.notifications.Set('hullNotificationEnabled', checkbox.checked)




